package com.wish.group05.base.service.impl;

import com.wish.group05.base.dto.RequestSearchSfsDto;
import com.wish.group05.base.dto.ResponseSearchSfsDto;
import com.wish.group05.base.dto.SfContractDetailsResponseDTO;
import com.wish.group05.base.entity.CwPaymentPlan;
import com.wish.group05.base.entity.JrProduct;
import com.wish.group05.base.entity.SfContract;
import com.wish.group05.base.mapper.SfContractMapper;
import com.wish.group05.base.service.ICwPaymentPlanService;
import com.wish.group05.base.service.IJrProductService;
import com.wish.group05.base.service.ISfContractService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wish.group05.base.util.MyJinRongUtils;
import com.wish.group05.common.core.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author houzehui
 * @since 2022-05-23
 */
@Service
public class SfContractServiceImpl extends ServiceImpl<SfContractMapper, SfContract> implements ISfContractService {

    @Autowired
    ISfContractService sfContractService;
    @Autowired
    ICwPaymentPlanService iCwPaymentPlanService;
    @Autowired
    IJrProductService iJrProductService;

    @Override
    public List<ResponseSearchSfsDto> financialList(RequestSearchSfsDto requestSearchSfsDto) {
        return getBaseMapper().financialList(requestSearchSfsDto);
    }

    // 查询收房分期 - 付款计划（ 已付款）
    private int getCwPaymentPlanPaidCount(Long sfContractId) {
        Map<String, Object> param = new HashMap<>();
        param.put("contract_type", 1);
        param.put("contract_id", sfContractId);
        param.put("pay_type",1);
        param.put("pay_state", 2);
        param.put("bill_type", 3);
        param.put("item_type", 3);
        return iCwPaymentPlanService.listByMap(param).size();

    }

    // 查询收房分期 - 付款计划（ 未付款）
    private List<CwPaymentPlan> getCwPaymentPlanList(Long sfContractId) {
        Map<String, Object> param = new HashMap<>();
        param.put("contract_type",1);
        param.put("contract_id", sfContractId);
        param.put("pay_type",1);
        param.put("pay_state",1);
        param.put("bill_type",3);
        param.put("item_type",3);

        List<CwPaymentPlan> cwPaymentPlanEntities = iCwPaymentPlanService.listByMap(param);
        return cwPaymentPlanEntities;
    }

    @Override
    public SfContractDetailsResponseDTO getSfContract(Long id) {
        SfContract sfce = sfContractService.getById(id);
        SfContractDetailsResponseDTO sfdto = new SfContractDetailsResponseDTO();
        BeanUtils.copyProperties(sfce, sfdto);

        // 查询收房分期 - 付款计划（ 未付款）
        List<CwPaymentPlan> payList = getCwPaymentPlanList(id);
        double balance = 0;
        Date startDate = null;
        if (payList.size() > 0) {
            for (CwPaymentPlan r : payList) {
                //BigDecimal叠加
                balance = MyJinRongUtils.add(balance, r.getPaymentAmount().doubleValue());
                if (null == startDate) {
                    startDate = r.getPaymentDaysBegin();
                } else if (1 == startDate.compareTo(r.getPaymentDaysBegin())) {
                    startDate = r.getPaymentDaysBegin();
                }
            }
        }
        //租约期限结束时间
        Date endDate = sfce.getLeaseEndTime();
        sfdto.setEndDate(endDate);
        sfdto.setStartDate(startDate);
        // 根据一段时间区间，按月份拆分成多个时间段
        List<MyJinRongUtils.KeyValueForDate> splitMonth = MyJinRongUtils.getSplitMonthForDate(startDate, endDate);
        if (null == splitMonth) {
            //剩余合同期限
            sfdto.setPeriods(0);
        } else {
            // 期数
            sfdto.setPeriods(splitMonth.size());
        }
        // 查询收房分期 - 付款计划（ 已付款）
        int count = getCwPaymentPlanPaidCount(id);
        // 计算 借款金额 期数
        if (count == 0) {
            //计算未付款
            double div = MyJinRongUtils.div(balance, splitMonth.size(), 2);

            //未付款总钱数减一期钱
            balance = MyJinRongUtils.sub(balance, div);

            Calendar cl = Calendar.getInstance();
            cl.setTime(sfdto.getStartDate());
            // 不加一个月
            cl.add(Calendar.MONTH, 1);
            sfdto.setStartDate(cl.getTime());
            // 期数
            sfdto.setPeriods(splitMonth.size() - 1);
            //sfdto.setPeriods(splitMonth.size());
            // 借款金额
            sfdto.setBalance(balance);
            // 授信额
            sfdto.setSxBalance(balance);
        } else {
            // 借款金额
            sfdto.setBalance(balance);
            // 授信额
            sfdto.setSxBalance(balance);
        }
        return sfdto;
    }

    @Override
    public SfContractDetailsResponseDTO getSfContractStagingCalculation(Long sfContractId, Long productId) {
        // 收房贷计算  contractId 合同id
        SfContract sfce = sfContractService.getById(sfContractId);
        SfContractDetailsResponseDTO sfdto = new SfContractDetailsResponseDTO();
        BeanUtils.copyProperties(sfce, sfdto);

        // 查询收房分期
        // 付款计划（未付款）
        List<CwPaymentPlan> payList = getCwPaymentPlanList(sfContractId);
        //productId金融产品id
        JrProduct product = iJrProductService.getById(productId);

        // 计算授信额   授信额度(单位：%，比如80%，存的是80)
        Double creditLine = MyJinRongUtils.div(Double.parseDouble(product.getCreditLine()+""), 100, 2);

        double balance = 0;
        if (payList.size() > 0) {
            for (CwPaymentPlan pay : payList) {
                //PaymentAmount 支付金额（应付金额）
                balance = MyJinRongUtils.add(balance, pay.getPaymentAmount().doubleValue());
            }
        }

        // 获取未付款的期数
        int size = payList.size();
        //支付方式(押X付Y的Y）
        Integer paymentType = sfce.getPaymentType();
        //进行乘法运算
        double period = MyJinRongUtils.mul(size, paymentType);

        // 期数
        sfdto.setPeriods(new Double(period).intValue());
        // 总金额
        sfdto.setBalance(balance);
        // 授信总额
        double sxBalance = MyJinRongUtils.mul(sfdto.getBalance(), creditLine);
        sfdto.setSxBalance(sxBalance);
        return sfdto;
    }

}
